package com.it.filter;

import com.it.common.ErrorCode;
import com.it.exception.SystemException;
import com.it.model.LoginUser;
import com.it.model.User;
import com.it.utils.Assert;
import com.it.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.servlet.HandlerExceptionResolver;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    @Qualifier("handlerExceptionResolver")
    private HandlerExceptionResolver exceptionResolver;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        // 获取 token
        String token = request.getHeader("token");
        if (!StringUtils.hasText(token)) {
            filterChain.doFilter(request, response);
            return;
        }

        String userName;
        try {
            Claims claims = JwtUtil.parseJWT(token);
            userName = claims.getSubject();
        } catch (Exception e) {
            resolveException(request, response);
            return;
        }

        List<User> users = new ArrayList<User>(){{
           add(new User("panxiyi","$2a$10$E828hdJKguT0pqt3pWA0Nui1CeJ7.cqXZE.P.TtEw.9l95lO94Bs."));
           add(new User("wangke", "$2a$10$aEQ/WP0t/VBDLxaaRo4lnuXyde.5hoakXoCaiCG4fowmV4F32YBJW"));
        }};

        List<User> filterUsers = users.stream().filter(bo -> !com.it.utils.StringUtils.isBlank(userName) && userName.equals(bo.getUserName())).collect(Collectors.toList());
        Assert.notNull(!filterUsers.isEmpty(), ErrorCode.LOGIN_ERROR);
        List<String> permissions = Arrays.asList("1","2");
        LoginUser loginUser = new LoginUser(filterUsers.get(0), permissions);

//        LoginUser loginUser = redisCache.getCacheObject(SystemConstants.REDIS_USER_ID_PREFIX + userId);
//        if (loginUser == null) {
//            resolveException(request, response);
//            return;
//        }

        // 将封装的 authentication 放到 SecurityContext 中
        Authentication authentication = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication);
        filterChain.doFilter(request, response);
    }

    private void resolveException(HttpServletRequest request, HttpServletResponse response){
        exceptionResolver.resolveException(request, response, null, new SystemException(ErrorCode.NOT_LOGIN));
    }
}
